package com.lovezy.platform.member.service.impl;

import com.lovezy.platform.common.extend.ExtendService;
import com.lovezy.platform.common.prop.Constant;
import com.lovezy.platform.core.codec.CodecUtil;
import com.lovezy.platform.core.exception.ServiceException;
import com.lovezy.platform.core.mq.MessageProducer;
import com.lovezy.platform.core.utils.Container;
import com.lovezy.platform.core.utils.ObjectUtil;
import com.lovezy.platform.core.valid.ValidatorUtil;
import com.lovezy.platform.discuz.service.DiscuzMemberService;
import com.lovezy.platform.discuz.vo.DiscuzMemberVo;
import com.lovezy.platform.member.form.LoginForm;
import com.lovezy.platform.member.form.RegisterForm;
import com.lovezy.platform.member.form.SmsLoginForm;
import com.lovezy.platform.member.model.Member;
import com.lovezy.platform.member.service.LoginResponse;
import com.lovezy.platform.member.service.LoginService;
import com.lovezy.platform.member.service.MemberService;
import com.lovezy.platform.member.service.RegistrationService;
import com.lovezy.platform.member.vo.MemberVo;
import com.lovezy.platform.message.mobile.enums.SmsIllegalEnum;
import com.lovezy.platform.message.mobile.enums.SmsTypeEnum;
import com.lovezy.platform.message.mobile.exception.IllegalMobileException;
import com.lovezy.platform.message.mobile.service.SmsSenderService;
import com.lovezy.platform.message.mobile.service.SmsServiceTarget;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

import static com.lovezy.platform.member.exception.MemberExceptionEnum.PHONE_MEMBER_NOT_EXISTS;
import static com.lovezy.platform.member.service.LoginResponse.dzLogin;
import static com.lovezy.platform.member.service.LoginResponse.siteLogin;

/**
 * 登陆服务实现
 * Created by jin on 2017/11/5.
 */
@Service
public class LoginServiceImpl implements LoginService{

    @Autowired
    private MemberService memberService;

    @Autowired
    private DiscuzMemberService discuzMemberService;

    @Autowired
    private SmsSenderService smsSenderService;

    @Autowired
    @Qualifier("smsMessageProducer")
    private MessageProducer smsMessageProducer;

    @Autowired
    @Qualifier("mobileRegistrationService")
    private RegistrationService mobileRegistrationService;

    @Autowired
    private ExtendService extendService;

    private final Log log = LogFactory.getLog(this.getClass());

    @Override
    public LoginResponse login(LoginForm loginForm) {
        ValidatorUtil.validate(loginForm);
        Member m = memberService.findByUserNameAndPassword(loginForm.getLoginName(), loginForm.getPassword());
        MemberVo memberVo = new MemberVo();
        ObjectUtil.copy(m, memberVo);
        return siteLogin(memberVo);
    }

    @Override
    public LoginResponse loginByDz(LoginForm loginForm) {
        ValidatorUtil.validate(loginForm);
        DiscuzMemberVo member = discuzMemberService.login(loginForm.getLoginName(), loginForm.getPassword());
        return dzLogin(member);
    }

    @Override
    public void sendLoginSms(@NotNull String mobile) {
        Optional<Member> mobileMember = memberService.findByMobile(mobile);
        Member member = mobileMember.orElseThrow(() -> new ServiceException(PHONE_MEMBER_NOT_EXISTS.getErrorCode(), PHONE_MEMBER_NOT_EXISTS.getErrorMsg()));

        String authKey = CodecUtil.randomDigit(6);
        SmsServiceTarget target = new SmsServiceTarget();
        target.setMemberId(member.getMemberId());
        target.setType(SmsTypeEnum.MEMBER_LOGIN);
        target.setAuthKey(authKey);
        target.setMobile(mobile);
        target.setText(authKey);
        target.setTemplateCode(Constant.REGISTER_TEMPLATE_CODE);
//        smsSenderService.sendSms(target);
        smsMessageProducer.send(target);

    }

    @Override
    @Transactional
    public LoginResponse loginByMobileSms(SmsLoginForm loginForm) {
        String mobile = loginForm.getMobile();
        Optional<Member> mobileMember = memberService.findByMobile(mobile);
        MemberVo vo;
        if (!mobileMember.isPresent()) {
            RegisterForm form = new RegisterForm();
            form.setAuthKey(loginForm.getCode());
            vo = mobileRegistrationService.regMember(form);
        } else {
            Container<Member> memberContainer = Container.empty();
            smsSenderService.verifyMobile(loginForm.getCode(), SmsTypeEnum.MEMBER_LOGIN, r -> {
                if (r.isSuccess()) {
                    boolean isThisMobile = r.getMobile().getMobileNumber().equals(loginForm.getMobile());
                    if (isThisMobile) {
                        Member m  = memberService.findByMemberId(r.getMobile().getMemberId());
                        memberContainer.set(m);
                        return true;
                    }else{
                        throw new IllegalMobileException(SmsIllegalEnum.NOT_FOUND);
                    }
                }else{
                    SmsIllegalEnum illegal = r.getIllegal();
                    throw new IllegalMobileException(illegal);
                }
            });
            vo = new MemberVo();
            ObjectUtil.copy(memberContainer.get(), vo);
        }

        return siteLogin(vo);
    }

    @Override
    public String refreshToken(String mid) {
        return extendService.refreshToken(mid);

    }

}
